package com.arcpan.Controller;

import com.arcpan.Constant.BaseConstant;
import com.arcpan.Entity.Dto.DownloadFileDto;
import com.arcpan.Entity.Dto.SessionWebUserDto;
import com.arcpan.Entity.Dto.UploadResultDto;
import com.arcpan.Entity.Query.FileInfoQuery;
import com.arcpan.Entity.Vo.FileInfo;
import com.arcpan.Exception.BaseException;
import com.arcpan.Mapper.FileInfoMapper;
import com.arcpan.Result.PageResult;
import com.arcpan.Result.Result;
import com.arcpan.Service.FileInfoService;
import com.arcpan.Util.StringTools;
import com.arcpan.annotation.GlobalInterceptor;
import com.arcpan.annotation.VerifyParams;
import com.arcpan.component.RedisComponent;
import com.arcpan.component.RedisUtils;
import com.arcpan.config.AppConfig;
import com.arcpan.enums.FileCategoryEnum;

import com.arcpan.enums.FileDelFlagEnums;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.Locale;

@RestController
@RequestMapping("/file")
public class FileInfoController {
    @Resource
    private AppConfig appConfig;
    @Resource
    private FileInfoService fileInfoService;
    @Resource
    private FileInfoMapper fileInfoMapper;
    @Resource
    private RedisComponent redisComponent;
    @Resource
    private RedisUtils redisUtils;

    @RequestMapping("/rename")
    public Result rename(HttpSession httpSession, @VerifyParams(required = true) String fileId, @VerifyParams(required = true) String fileName) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String userId = sessionWebUserDto.getUserId();

        FileInfo fileInfo = fileInfoService.rename(fileId, userId, fileName);
        return Result.success(fileInfo);

    }

    @RequestMapping("/loadAllFolder")
    public Result loadAllFolder(@VerifyParams(required = true) String filePid,
                                @VerifyParams(required = true) String currentFileIds, HttpSession httpSession) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        FileInfoQuery fileInfoQuery = new FileInfoQuery();
        fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
        fileInfoQuery.setFilePid(filePid);
        if (!StringTools.isEmpty(currentFileIds)) {
            fileInfoQuery.setExcludeFileIdArray(currentFileIds.split(","));
        }
        fileInfoQuery.setDelFlag(FileDelFlagEnums.USING.getFlag());
        fileInfoQuery.setOrderBy("create_time desc");
        fileInfoQuery.setFolderType(1);
        List<FileInfo> list = fileInfoMapper.selectByQuery2(fileInfoQuery);

        return Result.success(list);
    }

    @RequestMapping("/changeFileFolder")
    public Result changeFileFolder(HttpSession httpSession, String fileIds, String filePid) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String userId = sessionWebUserDto.getUserId();

        fileInfoService.changeFilefolder(fileIds, filePid, userId);


        return Result.success();
    }

    @RequestMapping("/createDownloadUrl/{fileId}")
    public Result createDownloadUrl(HttpSession httpSession, @PathVariable("fileId") String fileId) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String userId = sessionWebUserDto.getUserId();
        FileInfoQuery fileInfoQuery = new FileInfoQuery();
        fileInfoQuery.setFileId(fileId);
        fileInfoQuery.setUserId(userId);
        FileInfo fileInfo = fileInfoMapper.selectByQuery1(fileInfoQuery);
        if (fileInfo == null) {
            throw new BaseException("文件不存在");
        }
        if (fileInfo.getFolderType().equals(1)) {
            throw new BaseException("不能下载文件夹");
        }
        String code = StringTools.getRandomNumber(BaseConstant.LENGTH_50);
        DownloadFileDto downloadFileDto = new DownloadFileDto();
        downloadFileDto.setDownloadCode(code);
        downloadFileDto.setFileId(fileId);
        downloadFileDto.setFilePath(fileInfo.getFilePath());
        downloadFileDto.setFileName(fileInfo.getFileName());
        savedownloadcode(code,downloadFileDto);
        return Result.success(code);
    }
    @RequestMapping("/download/{code}")
    public void download(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,@PathVariable("code") String code) throws UnsupportedEncodingException {
        DownloadFileDto downloadFileDto=getDownloadcode(code);
        if(null == downloadFileDto){
            return;
        }
        String filePath=appConfig.getProjectFolder()+BaseConstant.FILE_FOLDER_FILE+downloadFileDto.getFilePath();
        String fileName=downloadFileDto.getFileName();
        httpServletResponse.setContentType("application/x-msdownload; charset=UTF-8");
        if (httpServletRequest.getHeader("User-Agent").toLowerCase().indexOf("msie") > 0) {//IE浏览器
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } else {
            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
        }
        httpServletResponse.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\"");
        readFile(httpServletResponse,filePath);



    }

    private DownloadFileDto getDownloadcode(String code) {
        DownloadFileDto downloadFileDto= (DownloadFileDto) redisUtils.get(BaseConstant.REDIS_KEY_USER_FILE_TEMP_SIZE+code);
        return downloadFileDto;
    }

    private void savedownloadcode(String code,DownloadFileDto downloadFileDto) {
        redisUtils.setex(BaseConstant.REDIS_KEY_USER_FILE_TEMP_SIZE+code,downloadFileDto,300);

    }
    @RequestMapping("/delFile")
    public Result delFile(HttpSession httpSession, String fileIds){
SessionWebUserDto sessionWebUserDto= (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
String userId=sessionWebUserDto.getUserId();
fileInfoService.removeFile(fileIds,userId);
return Result.success();
    }


    @RequestMapping("/getFolderInfo")
    @GlobalInterceptor
    public Result getFolderInfo(HttpSession session, @VerifyParams(required = true) String path) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) session.getAttribute(BaseConstant.SESSION_KEY);
        String userId = sessionWebUserDto.getUserId();
        String[] patharray = path.split("/");
        FileInfoQuery fileInfoQuery = new FileInfoQuery();
        fileInfoQuery.setUserId(userId);
        fileInfoQuery.setFolderType(1);
        String orderBy = "field(file_id,\"" + StringUtils.join(patharray, "\",\"") + "\")";
        System.out.println(orderBy + "orderby");
        fileInfoQuery.setOrderBy(orderBy);
        fileInfoQuery.setFileIdArray(patharray);
        //"select * from file_info where file_id in ("1","2") orderBy field(file_id,"1","2")
        List<FileInfo> list = fileInfoMapper.selectByQuery2(fileInfoQuery);
        return Result.success(list);

    }

    @RequestMapping("/loadDataList")
    @GlobalInterceptor
    public Result loadDataList(HttpSession httpSession, FileInfoQuery fileInfoQuery, String category, Integer pageNo, Integer pageSize) {
        System.out.println(pageNo);
        if (!category.equals("all")) {
            fileInfoQuery.setFileCategory(FileCategoryEnum.getByCode(category).getCategory());

        }
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
        fileInfoQuery.setOrderBy("last_update_time desc");
        fileInfoQuery.setDelFlag(2);
        PageResult pageResult = fileInfoService.getByPage(fileInfoQuery, pageNo, pageSize);

        return Result.success(pageResult);
    }

    @RequestMapping("/uploadFile")
    @GlobalInterceptor
    public Result uploadFile(HttpSession httpSession, String fileId, MultipartFile file, @VerifyParams(required = true) String fileName,
                             @VerifyParams(required = true) String filePid,
                             @VerifyParams(required = true) String fileMd5,
                             @VerifyParams(required = true) Integer chunkIndex,
                             @VerifyParams(required = true) Integer chunks
    ) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        UploadResultDto uploadResultDto = fileInfoService.uploadFile(sessionWebUserDto, fileId, file, fileName, filePid, fileMd5, chunkIndex, chunks);
        return Result.success(uploadResultDto);
    }

    @RequestMapping("/getImage/{imageFolder}/{imageName}")
    @GlobalInterceptor(checkParam = true)
    public void getImage(HttpServletResponse response, @PathVariable("imageFolder") String imageFolder, @PathVariable("imageName") String imageName) {
        System.out.println("getImage");
        if (StringTools.isEmpty(imageFolder) || StringTools.isEmpty(imageName) || !StringTools.pathIsOk(imageFolder) || !StringTools.pathIsOk(imageName)) {
            return;

        }
        String imageSuffix = StringTools.getFileNameSuffix(imageName);
        String filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + imageFolder + "/" + imageName;
        System.out.println(filePath + "filePathsd");
        imageSuffix = imageSuffix.replace(".", "");
        String contentType = "image/" + imageSuffix;
        response.setContentType(contentType);
        response.setHeader("Content-Disposition", "inline");
        readFile(response, filePath);
    }

    @RequestMapping("/ts/getVideoInfo/{fileId}")
    @GlobalInterceptor(checkParam = true)
    public void getVideo(HttpServletResponse httpServletResponse, @PathVariable("fileId") String fileId, HttpSession httpSession) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String filePath = null;
        if (fileId.endsWith(".ts")) {
            String[] tsArray = fileId.split("_");
            String realFileId = tsArray[0];
            FileInfoQuery fileInfoQuery = new FileInfoQuery();
            fileInfoQuery.setFileId(realFileId);
            fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
            FileInfo fileInfo = fileInfoMapper.selectByQuery1(fileInfoQuery);
            String fileName = fileInfo.getFilePath();
            fileName = StringTools.getFileNameNoSuffix(fileName) + "/" + fileId;
            filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + fileName;
            System.out.println(filePath + "filePath1");


        } else {
            FileInfoQuery fileInfoQuery = new FileInfoQuery();
            fileInfoQuery.setFileId(fileId);
            fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
            FileInfo fileInfo = fileInfoMapper.selectByQuery1(fileInfoQuery);

            if (null == fileInfo) {
                return;
            }
            if (FileCategoryEnum.VIDEO.getCategory().equals(fileInfo.getFileCategory())) {
                String fileNameNoSuffix = StringTools.getFileNameNoSuffix(fileInfo.getFilePath());
                filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + fileNameNoSuffix + "/" + BaseConstant.M3U8_NAME;
            }
            File file1 = new File(filePath);
            if (!file1.exists()) {
                return;
            }
        }


        readFile(httpServletResponse, filePath);


    }

    @RequestMapping("/getFile/{fileId}")
    @GlobalInterceptor(checkParam = true)
    public void getFiles(HttpServletResponse httpServletResponse, @PathVariable("fileId") String fileId, HttpSession httpSession) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String filePath = null;
        if (fileId.endsWith(".ts")) {
            String[] tsArray = fileId.split("_");
            String realFileId = tsArray[0];
            FileInfoQuery fileInfoQuery = new FileInfoQuery();
            fileInfoQuery.setFileId(realFileId);
            fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
            FileInfo fileInfo = fileInfoMapper.selectByQuery1(fileInfoQuery);
            String fileName = fileInfo.getFilePath();
            fileName = StringTools.getFileNameNoSuffix(fileName) + "/" + fileId;
            filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + fileName;
            System.out.println(filePath + "filePath1");


        } else {
            FileInfoQuery fileInfoQuery = new FileInfoQuery();
            fileInfoQuery.setFileId(fileId);
            fileInfoQuery.setUserId(sessionWebUserDto.getUserId());
            FileInfo fileInfo = fileInfoMapper.selectByQuery1(fileInfoQuery);

            if (null == fileInfo) {
                return;
            }
            if (FileCategoryEnum.VIDEO.getCategory().equals(fileInfo.getFileCategory())) {
                String fileNameNoSuffix = StringTools.getFileNameNoSuffix(fileInfo.getFilePath());
                filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + fileNameNoSuffix + "/" + BaseConstant.M3U8_NAME;
            } else {
                filePath = appConfig.getProjectFolder() + BaseConstant.FILE_FOLDER_FILE + fileInfo.getFilePath();

            }
            File file1 = new File(filePath);
            if (!file1.exists()) {
                return;
            }
        }


        readFile(httpServletResponse, filePath);

    }

    @RequestMapping("/newFolder")
    @GlobalInterceptor(checkParam = true)
    public Result newFolder(HttpSession httpSession, @VerifyParams(required = true) String filePid,
                            @VerifyParams(required = true) String fileName) {
        SessionWebUserDto sessionWebUserDto = (SessionWebUserDto) httpSession.getAttribute(BaseConstant.SESSION_KEY);
        String userId = sessionWebUserDto.getUserId();
        FileInfo fileInfo = fileInfoService.newFolder(filePid, userId, fileName);


        return Result.success(fileInfo);


    }


    protected void readFile(HttpServletResponse response, String filePath) {
        if (!StringTools.pathIsOk(filePath)) {
            return;
        }
        OutputStream out = null;
        FileInputStream in = null;
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                return;
            }
            in = new FileInputStream(file);
            byte[] byteData = new byte[1024];
            out = response.getOutputStream();
            int len = 0;
            while ((len = in.read(byteData)) != -1) {
                out.write(byteData, 0, len);
            }
            out.flush();
        } catch (Exception e) {

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {

                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {

                }
            }
        }
    }
}
